#include "CommonApps.h"
#include "SenetBoardDraft.h"
#include "definitions.h"
#include "Expectimax.h"
#include "ExpectimaxNegamax.h"
#include "GameTimer.h"
#include "ExpectimaxPlayer.h"
#include "ExpectimaxNegamaxPlayer.h"
#include "Star1Player.h"
#include "Star2Player.h"
#include "Star1pPlayer.h"
#include <vector>
#include <iostream>
#include <Windows.h>

void draw(const SenetBoard& board)
{
	std::vector<std::string> names;
	names.push_back(std::string("white"));
	names.push_back(std::string("black"));
	std::cout << "\n\n\n";
	board.drawBoard(names);
}

void printTime(char* player, int ticks, int sticksRes)
{
	std::cout << "player " << player << " ticks: " << ticks << " sticksRes: " << sticksRes << std::endl <<std::endl;
}

static int x = 0;

int main(int argc, char **argv)
{
	// param 1: numSticks
	// param 2: boardSize
	// param 3: piecesNum
	// param 4: required depth
	GameTimer::TimeParams tp;

	//srand((unsigned)time(0));
	srand(time(NULL));

	tp.timePerGame = 100;
	tp.timePerGame_limit = false;
	tp.timePerMove = 5;
	tp.timePerMove_limit = false;
	GameTimer timer(tp);

	int numSticks = 6;
	int boardSize = 30;
	int piecesNum = 1;
	int depth = 6;

	if (argc == 1 /* no args */)
	{
		std::cout << "Using internal game parameters!";

	}
	else
	{
		numSticks = atoi(argv[1]);
		boardSize = atoi(argv[2]);
		piecesNum = atoi(argv[3]);
		depth = atoi(argv[4]);
	}


	SenetBoard board(boardSize, piecesNum, 0, 0, numSticks, Definitions::WHITE);
	board.createRandomBoard(piecesNum, piecesNum);
	draw(board);
	ExpectimaxPlayer expectimaxPlayer(Definitions::WHITE, tp, 1000);
	Star1pPlayer star1player(Definitions::WHITE, tp, 1000);

	expectimaxPlayer.initGame(boardSize ,piecesNum, numSticks, board);
	star1player.initGame(boardSize, piecesNum, numSticks, board);


	SenetMove expectimaxMove;
	SenetMove star25Move;
	int now, exp_time, s1ff, s1ft, s1tf, s1tt ;
	// 	for (int i = 0; i< 25; ++i)
	// 	{
	// 		for (int depth = 1; depth < 10; ++depth)
	// 		{		
	// 			for (int sticksRes = 1; sticksRes <= numSticks; ++sticksRes)
	//			{

	int sticksRes = numSticks;

	std::cout << std::endl;
	expectimaxPlayer.overrideSticksDepth(sticksRes, depth, true);
	star1player.overrideSticksDepth(sticksRes, depth, true);

	now = GetTickCount();
	expectimaxPlayer.makeMove(board, expectimaxMove);
	exp_time = GetTickCount() - now;
	printTime("expectimaxPlayer", exp_time, sticksRes);

	star1player.m_algorithm.SetReorder(true, false);
	now = GetTickCount();
	star1player.makeMove(board, star25Move);
	s1tf = GetTickCount() - now;
	printTime("star1player: using chance = TRUE, minimax = FALSE", s1tf, sticksRes);

	star1player.m_algorithm.SetReorder(false, true);
	now = GetTickCount();
	star1player.makeMove(board, star25Move);
	s1ft = GetTickCount() - now;
	printTime("star1player: using chance = FALSE, minimax = TRUE", s1ft, sticksRes);

	star1player.m_algorithm.SetReorder(true, true);
	now = GetTickCount();
	star1player.makeMove(board, star25Move);
	s1tt = GetTickCount() - now;
	printTime("star1player: using chance = TRUE, minimax = TRUE", s1tt, sticksRes);

	star1player.m_algorithm.SetReorder(false, false);
	now = GetTickCount();
	star1player.makeMove(board, star25Move);
	s1ff = GetTickCount() - now;
	printTime("star1player: using chance = FALSE, minimax = FALSE", s1ff, sticksRes);

	std::cout << "************************************************************" << std::endl;

	if(expectimaxPlayer.m_algorithm.m_FinalBoardScore !=
		star1player.m_algorithm.m_FinalBoardScore)
	{
		float epsilon = expectimaxPlayer.m_algorithm.m_FinalBoardScore - star1player.m_algorithm.m_FinalBoardScore;
		epsilon = fabs(epsilon);
		if (epsilon > 0.00001)
		{
			int x;
			x= 10;
		}
		//				}
		// 
		// 				}
		// 			}
		// 		}

	}

	std::cout << "\n\nMARKER_MARKER_MARKER_MARKER";
	std::cout << ":" << exp_time << ":" << s1ff << ":" << s1tf << ":" << s1ft << ":" << s1tt << ":\n";

	return 0;

}